【アップデート】暖機不要で固定IPの Network Load Balancer ( NLB ) がSNIで複数の証明書をサポートしました
大栗です。
Network Load Balancer(NLB)でSNIをサポートして、複数の証明書を設定できるようになりました。
SNI(Server Name Indication)とは
SNI(Server Name Indication)とはRFC 6066に記述されている仕様です。「Server Name Indication」つまりサーバ名表示のことです。SNI以前の仕様ではIPアドレス/ポートに対して一つのSSL/TLS証明書しか設定が行なえませんでした。SNIによりサーバ名ごとにSSL/TLS証明書を設定できるようになり、リクエストから証明書を適用するサーバ名が判断して適用するようになります。
HTTPSリクエストのホストヘッダーを見れば判断できるだろうと思われるかもしれませんが、HTTPSで暗号化されるため証明書を適用する前にはホスト名を判断できません。そこで、SSL/TLSハンドシェイクのプロセス中でホスト名を送信することで解決しています。クライアントからサーバへ初回アクセスする時のClient Helloの中にserver_name
と言う型のExtensionsを含めてアクセス先のホスト名(host_name)を通知します。サーバ側ではClient Hello(とクライアントへ返すServer Hello)の内容を元にSSL/TLSで通信するための暗号形式などを決定するので、SSL/TLSで暗号化する前にアクセス先のホスト名が判断でき適切な証明書を適用します。
(この章の内容はALBでSNIが対応したときの記事をそのまま持ってきました。。。)
試してみる
下図のような環境を考えてみます。
NLBにsni-1.example.com
とsni-2.example.com
の2個のドメインを設定します。同様にACMで各々の証明書をNLBに設定します。EC2側はPHPのphpinfo()
でアクセス内容を表示します。
証明書の取得
ここでは証明書はACMで取得します。以下のエントリを参考に2つのドメインの証明書を発行してください。
EC2の設定
ここでは以下を前提とします。
- リージョン: 東京リージョン
- OS: Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0ff21806645c5e492 (64 ビット x86)
- インスタンスタイプ: t3.small
- Webサーバ:Apache HTTP Server 2.4.39
- PHP: 7.3.8
EC2のUserDataで以下のような内容を記載しておき、ApacheやPHPを導入します。
#!/bin/bash yum install -y httpd amazon-linux-extras install -y php7.3 cat <<EOF > /var/www/html/index.php <?php phpinfo(INFO_VARIABLES); EOF systemctl start php-fpm systemctl start httpd
NLBの場合はロードバランサーへのアクセス許可はEC2のセキュリティグループの設定になるため、アクセス元からのポート443
を許可しておきます。
ターゲットグループの作成
以下の内容でターゲットグループを作成します。
項目名 | 値 | 備考 |
---|---|---|
ターゲットグループ名 | php-target | |
プロトコル | TCP | |
ポート | 80 | |
ターゲットの種類 | インスタンス | |
VPC | <EC2を設置したVPC> | |
ヘルスチェックの設定 プロトコル | TCP | |
ヘルスチェックの設定 ポート | トラフィックポート |
作成したターゲットグループのターゲットとして2台のEC2を設定します。
NLBの作成
NLB(Network Load Balancer)を作成します。
1. ロードバランサーの設定
項目名 | 値 | 備考 |
---|---|---|
名前 | sni-nlb | |
スキーマ | インターネット向け | |
ロードバランサーのプロトコル | TLS(セキュア TCP) | |
ロードバランサーのポート | 443 | |
アベイラビリティゾーン | <対象VPCのパブリックなサブネット> |
2. セキュリティ設定の構成
項目名 | 値 | 備考 |
---|---|---|
証明書タイプ | ACM から証明書を選択する | |
証明書の名前 | sni-1.example.com | デフォルトの証明書です |
セキュリティポリシー | ELBSecurityPolicy-TLS-1-2-2017-01 | 安全なプロトコルのみを許可します |
3. ルーティングの設定
項目名 | 値 | 備考 |
---|---|---|
ターゲットグループ | 既存のターゲットグループ | |
名前 | sni-target | |
ターゲットの種類 | インスタンス | |
プロトコル | TCP | |
ポート | 80 | |
ヘルスチェック プロトコル | TCP | |
ヘルスチェックの設定 ポート | トラフィックポート |
4. ターゲットの登録
先程設定したEC2が設定されていることを確認して作成します。
5. 確認
設定内容を確認して、作成
をクリックします。
SNIの設定
作成したNLBのリスナーで証明書の表示/編集
をクリックします。
+
記号をクリックします。
sni-2.example.com
の証明書を選択して追加
をクリックします。
DNSの設定
ここではRoute 53で登録します。
このような形で、Alias Targetをsni-1.example.com
とsni-2.example.com
で登録します。エイリアス先でNLBの登録する場合はNLBのDNS名を入力します。
アクセスしてみる
まずはhttps://sni-1.example.com/index.php
にアクセスしてみます。するとsni-1の内容が表示されます。
証明書も確認してみるとsni-1.example.com
の証明書でアクセスしています。sni-1の内容が表示されます。
次にhttps://sni-2.example.com/index.php
にアクセスしてみます。するとsni-2の内容が表示されます。
証明書も確認してみるとsni-2.example.com
の証明書でアクセスしています。
特殊なパターンとしてIPアドレスでアクセスする場合を試してみます。
証明書を確認してみるとsni-1.example.comの証明書でアクセスしています。これはNLBのリスナーでメインの証明書をsni-1.example.comにしているためです。
このようにホスト名によって別の証明書でアクセスしていることが確認できました。
さいごに
NLBでもSNIに対応して複数の証明書を設定できるようになりました。複数のエンドポイントをまとめる時に有効かと思います。個人的にはエンドポイントごとに別のロードバランサーを設定したいのですが、選択肢が増えたため構成の自由度が上がったと思います。